package com.ruoyi.asms.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.ruoyi.ams.controller.AmsAssetTypeController;
import com.ruoyi.ams.controller.AmsOwnAddressController;
import com.ruoyi.asms.domain.*;
import com.ruoyi.asms.domain.bo.UnResovleFaultMsgBo;
import com.ruoyi.asms.domain.bo.UrgeWorkBo;
import com.ruoyi.asms.domain.vo.*;
import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.AmsOwnAddress;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.BusinessUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.rabbitmq.constant.RabbitmqConstants;
import com.ruoyi.common.rabbitmq.domain.EmailNotifyTemplate;
import com.ruoyi.security.service.TokensService;
import com.ruoyi.common.wx.config.WxMaConfiguration;
import com.ruoyi.common.wx.config.WxSubcribConfig;
import com.ruoyi.file.controller.SysFileController;
import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.controller.SysUserController;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Description
 * @Author YangJun
 * @Date 2021年11月8日 15:00:43
 **/
@Service
@Async
public class AsyncService {
    @Autowired
    private IAsmsFaultService asmsFaultService;
    @Autowired
    private IFaultInfoViewService faultInfoViewService;
    @Autowired
    private IAsmsFaultAssetService asmsFaultAssetService;
    @Autowired
    private IAsmsFaultReportStageService asmsFaultReportStageService;
    @Autowired
    private IAsmsFaultDispatchStageService asmsFaultDispatchStageService;
    @Autowired
    private IAsmsFaultConfirmStageService asmsFaultConfirmStageService;
    @Autowired
    private IAsmsFaultFeedbackStageService asmsFaultFeedbackStageService;
    @Autowired
    private IAsmsFaultAssetReasonService asmsFaultAssetReasonService;
    @Autowired
    private IAsmsMaintenanceChargeInfoService asmsMaintenanceChargeInfoService;
    @Autowired
    private IAsmsMaintenanceAssetService asmsMaintenanceAssetService;
    @Autowired
    private IAsmsAssetFullInfoService asmsAssetFullInfoService;
    @Autowired
    private IAsmsFaultResolveStageService asmsFaultResolveStageService;
    @Autowired
    private IAsmsOwnChargeInfoService asmsOwnChargeInfoService;
    @Autowired
    private TokensService tokenService;
//    @Autowired
//    private RemoteUserService remoteUserService;
//    @Autowired
//    private RemoteAssetAddressService remoteAssetAddressService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
//    @Autowired
//    private RemoteFileService remoteFileService;
//    @Autowired
//    private RemoteAssetTypeService remoteAssetTypeService;
    @Autowired
    private AsmsReusingService asmsReusingService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SysUserController userController;
    @Autowired
    private SysFileController fileController;
    @Autowired
    private SysDeptController deptController;
    @Autowired
    private AmsOwnAddressController ownAddressController;
    @Autowired
    private AmsAssetTypeController assetTypeController;


    /**
     * 故障报修通知
     *
     * @param asmsFault
     * @param asmsFaultAsset
     * @param findUser
     */
    public void sendReportFaultWxSubscribeMsg(AsmsFault asmsFault, AsmsFaultAsset asmsFaultAsset, SysUser findUser) {
        Long addressId = asmsFault.getAddressId();
        Long faultAssetId = asmsFaultAsset.getFaultAssetId();
        Long addressTypeId = asmsFaultAsset.getAssetTypeId();
        Long mDeptId = asmsFaultAsset.getMaintenanceDeptId();
        Long ownDeptId = asmsFaultAsset.getOwnDeptId();
        final WxMaService wxService = WxMaConfiguration.getMaService();
        Set<String> ownOpenIds = new HashSet<>();
        Set<String> mOpenIds = new HashSet<>();
        //负责人,先找有没有专门的报修负责人
        List<AsmsOwnChargeInfo> ownChargeInfos = asmsOwnChargeInfoService.list(new QueryWrapper<AsmsOwnChargeInfo>()
                .eq(AsmsOwnChargeInfo.OWN_DEPT_ID, ownDeptId).or()
                .like(AsmsOwnChargeInfo.OWN_CHARGE_ADDRESS_IDS, "," + addressId + ",").or()
                .likeLeft(AsmsOwnChargeInfo.OWN_CHARGE_ADDRESS_IDS, "," + addressId).or()
                .likeRight(AsmsOwnChargeInfo.OWN_CHARGE_ADDRESS_IDS, addressId + ",").or()
                .like(AsmsOwnChargeInfo.OWN_CHARGE_ASSET_TYPES, "," + addressTypeId + ",").or()
                .likeLeft(AsmsOwnChargeInfo.OWN_CHARGE_ASSET_TYPES, "," + addressTypeId).or()
                .likeRight(AsmsOwnChargeInfo.OWN_CHARGE_ASSET_TYPES, addressTypeId + ",")
        );
        //没有就找部门负责人
        if (ownChargeInfos.size() > 0) {
            Set<Long> userIds = new HashSet<>();
            ownChargeInfos.forEach(u -> userIds.add(u.getUserId()));
            ownOpenIds.addAll(getDeptAntherChargers(userIds));
        } else {
            ownOpenIds.addAll(getDeptChargers(ownDeptId, 1));
        }
        //先找专门的负责人
        List<AsmsMaintenanceChargeInfo> mChargeInfos = asmsMaintenanceChargeInfoService.list(new QueryWrapper<AsmsMaintenanceChargeInfo>()
                .eq(AsmsMaintenanceChargeInfo.MAINTENANCE_DEPT_ID, mDeptId)
                .eq(AsmsMaintenanceChargeInfo.TYPE, 1).or()
                .like(AsmsMaintenanceChargeInfo.CHARGE_ASSET_TYPES, "," + addressTypeId + ",").or()
                .likeLeft(AsmsMaintenanceChargeInfo.CHARGE_ASSET_TYPES, "," + addressTypeId).or()
                .likeRight(AsmsMaintenanceChargeInfo.CHARGE_ASSET_TYPES, addressTypeId + ",").or()
                .like(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_ADDRESS_IDS, "," + addressId + ",").or()
                .likeLeft(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_ADDRESS_IDS, "," + addressId).or()
                .likeRight(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_ADDRESS_IDS, addressId + ",").or()
                .like(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_DEPT_IDS, "," + ownDeptId + ",").or()
                .likeLeft(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_DEPT_IDS, "," + ownDeptId).or()
                .likeRight(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_DEPT_IDS, ownDeptId + ",")
        );

        //再找部门负责人
        if (mChargeInfos.size() == 0) {
            mOpenIds.addAll(getDeptChargers(mDeptId, 2));
        } else {
            Set<Long> userIds = new HashSet<>();
            mChargeInfos.forEach(u -> userIds.add(u.getUserId()));
            mOpenIds.addAll(getDeptAntherChargers(userIds));
        }

        //通知负责人
        R<AmsOwnAddress> addressInfo = ownAddressController.getInfoR(addressId);
        if (addressInfo.getCode() == R.FAIL) {
            throw new ServiceException(addressInfo.getMsg());
        }
        R<SysDept> rDept = deptController.getDeptById(ownDeptId);
        if (rDept.getCode() == R.FAIL) {
            throw new ServiceException(rDept.getMsg());
        }
        String address = rDept.getData().getDeptShortName() + addressInfo.getData().getFullName();
        String shortAddress = address;

        if (address.length() > 10) {
            shortAddress = address.substring(0, 7) + "...";
        }
        ArrayList<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing2", asmsFaultAsset.getDescription()),//故障描述
                new WxMaSubscribeMessage.MsgData("thing3", findUser.getNickName()),//报修人姓名
                new WxMaSubscribeMessage.MsgData("phone_number4", findUser.getPhonenumber()),//报修人电话
                new WxMaSubscribeMessage.MsgData("time5", DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, asmsFaultAsset.getCreateTime())),//报修时间
                new WxMaSubscribeMessage.MsgData("thing7", shortAddress)//报修地址
        );
        FaultBasicInfoVo vo = new FaultBasicInfoVo();
        BeanUtils.copyProperties(findUser, vo);
        BeanUtils.copyProperties(asmsFault, vo);
        BeanUtils.copyProperties(addressInfo.getData(), vo);
        vo.setCreateTime(asmsFaultAsset.getCreateTime());
        vo.setFullName(address);

        //vo.set
        for (String openId : mOpenIds) {
            if (StringUtils.isEmpty(openId)) {
                continue;
            }
            try {
                WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                        .templateId(WxSubcribConfig.FAULT_REPORT_NOTICE)
                        .data(msgData)
                        .toUser(openId)
                        .miniprogramState("formal")
                        .page("pages/component/paidan/paidan?list=" + JSONObject.toJSONString(vo))
                        .build());
            } catch (WxErrorException e) {
                e.printStackTrace();
            }
        }
        for (String openId : ownOpenIds) {
            if (StringUtils.isEmpty(openId)) {
                continue;
            }
            try {
                WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                        .templateId(WxSubcribConfig.FAULT_REPORT_NOTICE)
                        .data(msgData)
                        .toUser(openId)
                        .miniprogramState("formal")
                        .page("pages/component/result/result?info=" + faultAssetId)
                        .build());
            } catch (WxErrorException e) {
                e.printStackTrace();
            }
        }
    }

    private Set<String> getDeptAntherChargers(Set<Long> userIds) {
        Set<String> openIds = new HashSet<>();
        R<Map<Long, SysUser>> rUserList = userController.getUserListByIds(userIds.toArray(new Long[0]));
        if (rUserList.getCode() == R.FAIL) {
            throw new ServiceException(rUserList.getMsg());
        }
        rUserList.getData().values().forEach(sysUser -> {
            if (StringUtils.isNotEmpty(sysUser.getWxOpenId())) {
                openIds.add(sysUser.getWxOpenId());
            }
        });
        return openIds;
    }

    private Set<String> getDeptChargers(Long deptId, Integer type) {
        Set<String> openIds = new HashSet<>();
        R<List<SysUser>> rDeptCharger = new R<>();
        if (type == 1) {
            rDeptCharger = userController.getOwnDeptCharger(deptId);
        } else {
            rDeptCharger = userController.getMDeptCharger(deptId);
        }

        if (R.FAIL == rDeptCharger.getCode()) {
            throw new ServiceException(rDeptCharger.getMsg());
        }
        rDeptCharger.getData().forEach(sysUser -> {
            if (StringUtils.isNotEmpty(sysUser.getWxOpenId())) {
                openIds.add(sysUser.getWxOpenId());
            }
        });
        return openIds;
    }

    public void saveInspectionFault(ResolveInspectionVo vo) {

    }

    /**
     * 故障派单通知
     *
     * @param repair
     * @param finder
     * @param faultDescription
     * @param faultAddress
     * @param faultTime
     * @param assetTypeName
     * @param faultAssetId
     */
    public void sendDispatchWxSubscribeMsg(SysUser repair, SysUser finder, String faultDescription, String faultAddress,
                                           Long faultTime, String assetTypeName, Long faultAssetId, String descriptionImages, Integer status)  {
        String shortAddress ="";
        if (faultAddress.length() > 10) {
            shortAddress = faultAddress.substring(0, 7) + "...";
        }
        final WxMaService wxService = WxMaConfiguration.getMaService();
        GetMyRepairListVo info =new GetMyRepairListVo();
        info.setFaultAssetId(faultAssetId);
        info.setAddressFullName(faultAddress);
        info.setNickName(finder.getNickName());
        info.setPhonenumber(finder.getPhonenumber());
        info.setDescription(faultDescription);
        info.setDescriptionImages(descriptionImages);
        info.setCreateTime(faultTime);
        info.setStatus(status);

        String encodeInfo = "";
        try {
            encodeInfo = URLEncoder.encode(JSONObject.toJSONString(info), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.DISPATCH_NOTICE_TO_REPAIR)
                    .data(Lists.newArrayList(
                            new WxMaSubscribeMessage.MsgData("thing18", assetTypeName),//报修设备
                            new WxMaSubscribeMessage.MsgData("thing14", faultDescription),//问题描述
                            new WxMaSubscribeMessage.MsgData("thing19", finder.getNickName() + "【" + finder.getPhonenumber() + "】"),//申请人
                            new WxMaSubscribeMessage.MsgData("thing20", faultAddress),//报修区域
                            new WxMaSubscribeMessage.MsgData("time17", DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultTime))//报修时间
                    ))
                    .toUser(repair.getWxOpenId())
                    .miniprogramState("formal")
                    .page("pages/component/repairdeal/repairdeal?info=" + encodeInfo)
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.DISPATCH_NOTICE_TO_USER)
                    .data(Lists.newArrayList(
                            new WxMaSubscribeMessage.MsgData("thing8", repair.getNickName()),//故障描述
                            new WxMaSubscribeMessage.MsgData("phone_number3", repair.getPhonenumber()),//报修人姓名
                            new WxMaSubscribeMessage.MsgData("time2", DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, System.currentTimeMillis())),//报修人电话
                            new WxMaSubscribeMessage.MsgData("thing15", faultAddress)//报修时间
                    ))
                    .toUser(finder.getWxOpenId())
                    .miniprogramState("formal")
                    .page("pages/component/result/result?info=" + faultAssetId)
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    private void limitFieldValue(Object object) {
        Class<?> tClass = object.getClass();
        for (Field field : tClass.getDeclaredFields()) {
            field.setAccessible(true);

            if (field.getType() == String.class) {
                try {
                    String value = (String) field.get(object);
                    if (value != null && value.length() > 10) {
                        field.set(object, value.substring(0, 6) + "...");
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 故障处理结果通知
     *
     * @param vo
     */
    public void sendResolveWxSubscribeMsg(AsmsFaultResolveFaultVo vo) {
        limitFieldValue(vo);
        final WxMaService wxService = WxMaConfiguration.getMaService();
        Long faultAssetId = vo.getFaultAssetId();
        ArrayList<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing6", vo.getFaultDescription()),//故障描述
                new WxMaSubscribeMessage.MsgData("thing1", vo.getAssetTypeName()),//报修设备
                new WxMaSubscribeMessage.MsgData("thing5", vo.getAssetFaultSolution()),//处理结果
                new WxMaSubscribeMessage.MsgData("thing3", vo.getRepairName() + "—" + vo.getRepairPhone()),//处理人员
                new WxMaSubscribeMessage.MsgData("time4", DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, System.currentTimeMillis()))//完成时间
        );
        Set<Long> userIds = new HashSet<>();
        AsmsFaultReportStage reportStage = asmsFaultReportStageService.getOne(new QueryWrapper<AsmsFaultReportStage>().eq(AsmsFaultReportStage.FAULT_ASSET_ID, faultAssetId), false);
        AsmsFaultDispatchStage dispatchStage = asmsFaultDispatchStageService.getOne(new QueryWrapper<AsmsFaultDispatchStage>().eq(AsmsFaultDispatchStage.FAULT_ASSET_ID, faultAssetId), false);
        FaultInfoView fault = faultInfoViewService.getOne(new QueryWrapper<FaultInfoView>().eq(FaultInfoView.FAULT_ASSET_ID, faultAssetId), false);
        userIds.add(reportStage.getOwnChargeUserId());
        userIds.add(dispatchStage.getMaintenanceChargeUserId());
        userIds.add(fault.getFaultFindUserId());
        R<Map<Long, SysUser>> userListByIds = userController.getUserListByIds(userIds.toArray(new Long[0]));
        if (userListByIds.getCode() == R.FAIL) {
            throw new ServiceException(userListByIds.getMsg());
        }
        userListByIds.getData().values().forEach(user -> {
            try {
                WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                        .templateId(WxSubcribConfig.FAULT_RESOLVE_NOTICE)
                        .data(msgData)
                        .toUser(user.getWxOpenId())
                        .miniprogramState("formal")
                        .page("pages/component/result/result?info=" + faultAssetId)
                        .build());
            } catch (WxErrorException e) {
                e.printStackTrace();
            }
        });
    }

    public void autoDispatch(DispatchVo dispatchVo, AsmsMaintenanceChargeInfo chargeInfo) {

        List<AsmsMaintenanceChargeInfo> mChargeInfos = asmsMaintenanceChargeInfoService.list(new QueryWrapper<AsmsMaintenanceChargeInfo>()
                .eq(AsmsMaintenanceChargeInfo.MAINTENANCE_DEPT_ID, chargeInfo.getMaintenanceDeptId())
                .eq(AsmsMaintenanceChargeInfo.TYPE, 2).or()
                .like(AsmsMaintenanceChargeInfo.CHARGE_ASSET_TYPES, "," + chargeInfo.getChargeAssetTypes() + ",").or()
                .likeLeft(AsmsMaintenanceChargeInfo.CHARGE_ASSET_TYPES, "," + chargeInfo.getChargeAssetTypes()).or()
                .likeRight(AsmsMaintenanceChargeInfo.CHARGE_ASSET_TYPES, chargeInfo.getChargeAssetTypes() + ",").or()
                .like(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_ADDRESS_IDS, "," + chargeInfo.getMaintenanceChargeAddressIds() + ",").or()
                .likeLeft(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_ADDRESS_IDS, "," + chargeInfo.getMaintenanceChargeAddressIds()).or()
                .likeRight(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_ADDRESS_IDS, chargeInfo.getMaintenanceChargeAddressIds() + ",").or()
                .like(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_DEPT_IDS, "," + chargeInfo.getMaintenanceChargeDeptIds() + ",").or()
                .likeLeft(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_DEPT_IDS, "," + chargeInfo.getMaintenanceChargeDeptIds()).or()
                .likeRight(AsmsMaintenanceChargeInfo.MAINTENANCE_CHARGE_DEPT_IDS, chargeInfo.getMaintenanceChargeDeptIds() + ",")
        );
        if (mChargeInfos.size() > 0) {
            //没有默认派单人员
            R<SysUser> rUser = userController.getUserByIdR(mChargeInfos.get(0).getUserId());
            BusinessUtils.checkRemoteService(rUser);
            dispatchVo.setRepair(rUser.getData());
            asmsReusingService.dispatch(dispatchVo);
        }
    }

    public void sendFaultResolveMsgToReporter(AsmsFaultResolveFaultVo vo) {
        FaultInfoView fault = faultInfoViewService.getOne(new QueryWrapper<FaultInfoView>().eq(FaultInfoView.FAULT_ASSET_ID, vo.getFaultAssetId()), false);
        AsmsAssetFullInfo asmsAssetFullInfo = asmsAssetFullInfoService.getOne(new QueryWrapper<AsmsAssetFullInfo>().eq(AsmsAssetFullInfo.ASSET_ID, fault.getAssetId()));
        R<SysUser> rUser = userController.getUserByIdR(fault.getFaultFindUserId());
        BusinessUtils.checkRemoteService(rUser);
        if (StringUtils.isEmpty(rUser.getData().getEmail())) {
            return;
        }
        String content = "客户您好！";
        content += "\n您报修的故障：<<" + vo.getFaultDescription() + ">> 于" + DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, System.currentTimeMillis()) + "处理完成\n";
        content += "\n售后维护方信息:" + asmsAssetFullInfo.getMDeptShortName() + " " + vo.getRepairName() + " " + vo.getRepairPhone();
        content += "\n故障原因:" + " " + vo.getAssetFaultReason();
        content += "\n故障处理方式:" + " " + vo.getAssetFaultSolution();
        EmailNotifyTemplate emailTemplate = new EmailNotifyTemplate();
        //需要发送邮件消息
        emailTemplate.setTargetEmails(rUser.getData().getEmail());
        emailTemplate.setSubject("故障处理完成通知");
        content = content + "\n小焱资管运维\n" + DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS_Z);
        emailTemplate.setTextBody(content);
        rabbitTemplate.convertAndSend(RabbitmqConstants.EXCHANGE, RabbitmqConstants.EMAIL_ROUTINGKEY, emailTemplate);
    }

    public void sendInspectionResultWxSubscribeMsg(ResolveInspectionVo vo, Long chargeUserId, LoginUser inspector, String addressName) {

        //limitFieldValue(vo);
        R<SysUser> rUser = userController.getUserByIdR(chargeUserId);
        BusinessUtils.checkRemoteService(rUser);
        if(StringUtils.isEmpty(rUser.getData().getWxOpenId())){
            return;
        }
        final WxMaService wxService = WxMaConfiguration.getMaService();
        String InsStatus ="";
        //巡检结果类型(0：正常，1：设备故障，2：设备漏绑，3：安装位置码缺失，4：其他)
        switch (vo.getResultType()){
            case 0:InsStatus="正常";
            case 1:InsStatus="设备故障";
            case 2:InsStatus="设备漏绑";
            case 3:InsStatus="安装位置码缺失";
            case 4:InsStatus="其他";
        }
        if(addressName.length()>20){
            addressName=addressName.substring(0,19);
        }
        if(vo.getInspectionInfo().length()>20){
            vo.setInspectionInfo(vo.getInspectionInfo().substring(0,19));
        }
        ArrayList<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing2", inspector.getSysUser().getNickName()),//巡检人
                new WxMaSubscribeMessage.MsgData("thing9", addressName),//巡检地点
                new WxMaSubscribeMessage.MsgData("thing5", InsStatus),//巡检结果
                new WxMaSubscribeMessage.MsgData("thing6",vo.getInspectionInfo()),//巡检描述
                new WxMaSubscribeMessage.MsgData("time4", DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, System.currentTimeMillis()))//完成时间
        );
        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.INSPECTION_RESULT_NOTICE)
                    .data(msgData)
                    .toUser(rUser.getData().getWxOpenId())
                    .miniprogramState("formal")
                    //.page("pages/component/result/result?info=" + faultAssetId)
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将报修人的评价结果推送到维修人员的微信订阅消息
     *
     * @param resolveStage 故障处理阶段对象
     * @param vo           故障评价阶段对象
     */
    public void sendConfirmResultToWxMaSubscribe(AsmsFaultResolveStage resolveStage, AsmsFaultConfirmStageAppraiseVo vo) {
        if (resolveStage != null) {
            R<SysUser> rUser = userController.getUserByIdR(resolveStage.getFaultResolveUserId());
            if (rUser != null && rUser.getData() != null) {
                String wxOpenId = rUser.getData().getWxOpenId();
                if (wxOpenId == null) {
                    throw new ServiceException("wxOpenId must not be null!");
                }
                String date = DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, System.currentTimeMillis());
                String remark = "效率分:" + vo.getEfficiencyScore() + " 态度分:" + vo.getAttitudeScore()
                        + " 结果分:" + vo.getQualityScore();
                List<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                        new WxMaSubscribeMessage.MsgData("thing2", "匿名用户"),
                        new WxMaSubscribeMessage.MsgData("thing3", vo.getEvaluationContent()),
                        new WxMaSubscribeMessage.MsgData("time4", date),
                        new WxMaSubscribeMessage.MsgData("thing5", remark)
                );
                Set<String> deptChargers = getDeptChargers(resolveStage.getMaintenanceDeptId(), 2);
                deptChargers.add(wxOpenId);
                deptChargers.forEach(item->{
                    try {
                        WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                                .templateId(WxSubcribConfig.CONFIRM_RESULT_NOTICE)
                                .data(msgData)
                                .miniprogramState("formal")
                                .toUser(item)
                                .page("pages/component/result/result?info=" + vo.getFaultAssetId())
                                .build()
                        );
                    } catch (WxErrorException e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

    /**
     * 重新派单后发送通知给旧的维修人员
     *
     * @param dispatchUser   派单人员信息
     * @param newRepairName  新的维修人员姓名
     * @param faultAssetName 故障资产名
     * @param wxOpenId       旧的维修人员的wxOpenId
     */
    public void sendWxSubscribeToOldRepair(SysUser dispatchUser, String newRepairName, String faultAssetName, String wxOpenId) {
        if (wxOpenId == null) {
            throw new ServiceException("wxOpenId must not be null!");
        }
        //派单者信息
        String dispatchUserInfo = "";
        if (dispatchUser != null) {
            dispatchUserInfo = dispatchUser.getNickName() + dispatchUser.getPhonenumber();
        }

        //构造消息内容
        List<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing2", dispatchUserInfo), //转派人员
                new WxMaSubscribeMessage.MsgData("thing4", "维修" + faultAssetName), //工单内容
                new WxMaSubscribeMessage.MsgData("thing9", "工单已转让给" + newRepairName + "，你无需去维修") //温馨提示
        );

        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.AGAIN_DISPATCH_NOTICE_OLDREPAIR)
                    .data(msgData)
                    .miniprogramState("formal")
                    .toUser(wxOpenId)
                    //.page("pages/component/result/result?info=" + vo.getFaultAssetId())
                    .build()
            );
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    /**
     * 重新派单后发送订阅消息给新的维修人员
     *
     * @param repair           维修人员
     * @param finder           报修人员
     * @param faultDescription 故障描述
     * @param faultAddress     故障发送地点
     * @param faultTime        故障报修时间
     * @param faultAssetName    故障资产名称
     * @param faultAssetId     故障资产id
     */
    public void sendWxSubscribeToNewRepair(SysUser repair, SysUser finder, String faultDescription,
                                           String faultAddress, Long faultTime, String faultAssetName, Long faultAssetId) {
        if (repair.getWxOpenId() == null) {
            throw new ServiceException("wxOpenId must not be null!");
        }
        if (faultAddress.length() > 10) {
            faultAddress = faultAddress.substring(0, 7) + "...";
        }
        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.DISPATCH_NOTICE_TO_REPAIR)
                    .data(Lists.newArrayList(
                            new WxMaSubscribeMessage.MsgData("thing18", faultAssetName),//报修设备
                            new WxMaSubscribeMessage.MsgData("thing14", faultDescription),//问题描述
                            new WxMaSubscribeMessage.MsgData("thing19", finder.getNickName() + finder.getPhonenumber()),//申请人
                            new WxMaSubscribeMessage.MsgData("thing20", faultAddress),//报修区域
                            new WxMaSubscribeMessage.MsgData("time17", DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, faultTime))//报修时间
                    ))
                    .toUser(repair.getWxOpenId())
                    .miniprogramState("formal")
                    .page("pages/component/repairdeal/repairdeal?info=" + faultAssetId)
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    /**
     * 重新派单后通知报修人员
     *
     * @param finderWxOpenId 报修人员微信openId
     * @param faultAssetName 故障资产名
     * @param newRepair      新的维修人员
     */
    public void sendWxSubscribeToFinder(String finderWxOpenId, String faultAssetName, SysUser newRepair) {
        if (finderWxOpenId == null) {
            throw new ServiceException("wxOpenId must not be null!");
        }
        String newRepairName = "";
        String newRepairPhoneNumber = "";
        if (newRepair != null) {
            newRepairName = newRepair.getNickName();
            newRepairPhoneNumber = newRepair.getPhonenumber();
        }
        String time = DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, System.currentTimeMillis());
      
        List<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing1", faultAssetName), //报修项目
                new WxMaSubscribeMessage.MsgData("thing2", "维修师傅已变更为：" + newRepairName), //变更内容
                new WxMaSubscribeMessage.MsgData("phone_number3", newRepairPhoneNumber), //联系电话
                new WxMaSubscribeMessage.MsgData("date4", time) //变更时间
        );

        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.AGAIN_DISPATCH_NOTICE_FINDER)
                    .data(msgData)
                    .miniprogramState("formal")
                    .toUser(finderWxOpenId)
                    //.page("pages/component/result/result?info=" + vo.getFaultAssetId())
                    .build()
            );
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    public void sendDispatchToOldPlatform(String sug,String repairName,Integer faultId) {

        RestTemplate restTemplate = new RestTemplate();

        String url = "https://3firelink.xyz/maintenance/submit-repairInfo";
        // 请求头设置,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        //提交参数设置
        MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        map.add("suggestion", "");
        map.add("repairName", repairName);
        map.add("faultId", faultId);
        // 组装请求体
        HttpEntity<MultiValueMap<String, Object>> request =
                new HttpEntity<MultiValueMap<String, Object>>(map, headers);
        // 发送post请求，并打印结果，以String类型接收响应结果JSON字符串
        String result = restTemplate.postForObject(url, request, String.class);

        System.out.println(result);
    }

    public void sendResloveResultToOldPlatform(AsmsFaultResolveFaultVo vo) {

        RestTemplate restTemplate = new RestTemplate();

        String url = "https://3firelink.xyz/maintenance/new-accendant-submit-fault-result";
        // 请求头设置,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //提交参数设置
        try{
            MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
            String remark = asmsFaultAssetService.getById(vo.getFaultAssetId()).getRemark();
            Integer faultId = Integer.valueOf(remark);
            map.add("faultid",faultId);
            map.add("reason_id", 0);
            map.add("reason", vo.getAssetFaultReason());
            map.add("repairName", vo.getRepairName());
            map.add("solution", vo.getAssetFaultSolution());
            map.add("serialNumber", "");
            map.add("faultType", vo.getFaultType());
            map.add("resolveType", vo.getResolveType());
            // 组装请求体
            HttpEntity<MultiValueMap<String, Object>> request =
                    new HttpEntity<MultiValueMap<String, Object>>(map, headers);
            // 发送post请求，并打印结果，以String类型接收响应结果JSON字符串
            String result = restTemplate.postForObject(url, request, String.class);
            System.out.println(result);
        }catch (Exception ignored){

        }
    }

    /**
     * 当用户确认故障未解决时发送微信通知给技术人员
     */
    public void sendWxMsgWhenUnResovleFault(UnResovleFaultMsgBo bo) {
        if (bo.getOpenId() == null) {
            throw new ServiceException("wxOpenId must not be null!");
        }
        List<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing5", bo.getFinderInfo()), //报修人员
                new WxMaSubscribeMessage.MsgData("thing6", bo.getFaultAssetName()), //故障资产
                new WxMaSubscribeMessage.MsgData("thing7", bo.getFaultAddress()), //故障地址
                new WxMaSubscribeMessage.MsgData("thing8", bo.getRemark())  //备注
        );
        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.FAULT_NOT_RESOVLE_NOTICE)
                    .data(msgData)
                    .miniprogramState("formal")
                    .toUser(bo.getOpenId())
                    //.page("pages/component/result/result?info=" + vo.getFaultAssetId())
                    .build()
            );
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

    /**
     * 当用户催单时发送通知
     */
    public void sendWxMsgWhenUserUrgeWork(UrgeWorkBo bo) {
        if (bo.getOpenId() == null) {
            throw new ServiceException("wxOpenId must not be null!");
        }
        String time = DateUtils.parseLongToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_Z, bo.getTime());
        List<WxMaSubscribeMessage.MsgData> msgData = Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("thing1", bo.getContent()), //任务内容
                new WxMaSubscribeMessage.MsgData("thing2", bo.getAddress()), //任务地址
                new WxMaSubscribeMessage.MsgData("time3", time), //任务时间
                new WxMaSubscribeMessage.MsgData("thing4", bo.getRemark()) //备注
        );
        try {
            WxMaConfiguration.getMaService().getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
                    .templateId(WxSubcribConfig.URGU_WORK_ORDER_NOTICE)
                    .data(msgData)
                    .miniprogramState("formal")
                    .toUser(bo.getOpenId())
                    //.page("pages/component/result/result?info=" + vo.getFaultAssetId())
                    .build()
            );
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
    }

}
